import type { JSONSchema, Props } from '@/store/Schema'

type TransformComponent = {
  $componentName: string
  children: string | TransformComponent
  props?: Record<string, any>
}[]

const transformComponent: any = (children: any[]) => {
  return `${children
    .map((item: any) => {
      if (item.$componentName && item.componentid) {
        if (item.$componentName === 'Slot') {
          const slotWrapperStyle = !!item.children && item.children.length > 0
            ? '{minHeight:100}'
            : '{width:\'100%\',height:100,background:\'#f0f0f0\',textAlign:\'center\',lineHeight:\'100px\',fontSize:40,color:\'#8c8c8c\'}'
          return `[[<div componentid='${item.componentid
            }' style={${slotWrapperStyle}}>${!!item.children && item.children.length > 0 ? transformComponent(item.children || []) : '+'
            }</div>]]`
        }
        return `[[<${item.$componentName} componentid='${item.componentid
          }' ${popsToString(item.props || {}).replace(/"/g, '\'')}>${item.children ? transformComponent(item.children || []) : ''
          }</${item.$componentName}>]]`
      }
      else if (Array.isArray(item.children) && item.children.length > 0) {
        return transformComponent(item.children)
      }
      else {
        return ''
      }
    })
    .join('')}`
}

function searchJsxComponents(props: Record<string, any>) {
  for (const key in props) {
    const value = props[key]
    if (Array.isArray(value) && value.every(item => !!item.$componentName))
      props[key] = `[[<>${transformComponent(value)}</>]]`
    else if (typeof value === 'object')
      props[key] = searchJsxComponents(value)
  }
  return props
}

function popsToString(props: Record<string, any>) {
  return Object.keys(props)
    .map((key) => {
      if (key === 'children')
        return ''
      if (typeof props[key] === 'object') {
        // 正则匹配掉前后双括号
        return `${key}={${JSON.stringify(
          searchJsxComponents(props[key]),
        ).replace(/(["']?\[\[)|(\]\]["']?)/g, '')}}`
      }
      else if (typeof props[key] === 'string') {
        return `${key}="${props[key]}"`
      }
      else {
        return `${key}={${props[key]}}`
      }
    })
    .join(' ')
}

/**
 *
 * @param schema
 */
async function schemaTransform(jsonSchema: JSONSchema): Promise<string[]> {
  const importString = `${Object.entries((jsonSchema.componentsMap
    .reduce((pre, cur: any) => {
      // 组件是否能够解构
      if (cur.destructuring) {
        const $componentName = cur.$componentName.split('.')[0]
        if (Array.isArray(pre[cur.package]) && !pre[cur.package].includes($componentName))
          ((pre[cur.package]) as string[]).push($componentName)
        else if (!Array.isArray(pre[cur.package]))
          pre[cur.package] = [$componentName]
      }
      return pre
    }, {} as Record<string, string[]>))).filter(([packageName, modules])=>  {
      console.log(packageName, modules);
      
      return packageName !== 'undefined' 
    } ).map(([packageName, modules]) => {
      return `import ${Array.isArray(modules) ? `{${modules.join(',')}}` : modules}  from '${packageName}'`
    })
    .join('\n')}\n`

  const parseProps = (props: Props): any => {
    const newProps = JSON.parse(JSON.stringify(props))
    for (const key in newProps) {
      if (
        newProps.type
        && newProps.type === 'JSSlot'
        && newProps.value
        && Array.isArray(newProps.value)
      )
        return `<div>${render(props.value)}</div>`
      else if (
        newProps.type
        && newProps.type === 'JSSlot'
        && newProps.value
        && !Array.isArray(newProps.value)
      )
        return `<div>${render([props.value])}</div>`
      else if (typeof newProps[key] === 'object')
        return parseProps(newProps[key])
    }
    return newProps
  }

  const render = (
    jsonSchemaChildren: JSONSchema['componentsTree'],
  ): string[] => {
    return jsonSchemaChildren.map((component) => {
      if (component === null)
        return ''

      if (typeof component === 'string')
        return component

      const { $componentName, children = [], props, componentid } = component
      if (props && props.children)
        children.unshift(props.children)

      if ($componentName === 'Page') {
        return `${importString}
            function ${$componentName}(){
                return <div componentid="${componentid}" style={{height:'100%'}}>${children ? render(children).join('') : ''
          }</div>
            }
            export default ${$componentName}
          `
      }
      else {
        return `<${$componentName}  componentid='${componentid}'   ${popsToString(
          props || {},
        )}>${render(children || []).join('')}</${$componentName}>`
      }
    })
  }
  // 编译jsx
  return render(jsonSchema.componentsTree)
}

export default schemaTransform
